import { renderToString } from "react-dom/server";
import React from "react"; //只要有jsx语法 必须引入react
import express, { Router } from "express";
import { StaticRouter } from "react-router";
import { Provider } from "react-redux";
import { createServerStore } from "./store/store";
import { renderRoutes, matchRoutes } from "react-router-config";
import routes from "./routers/Routers";
import { Switch } from "react-router-dom";
import globalData from "./GlobalData";
require("es6-promise").polyfill();
require("isomorphic-fetch");
const app = express();
app.use(express.static("dist")); //设置静态目录，当前台访问静态资源(js,css,png,jpg....)都走当前目录下dist

app.get("*", function(req, res, next) {
  let context = {};
  globalData.clearCache();
  //调用renderToString把jsx转为html字符
  const store = createServerStore();
  let matchRoutersArr = matchRoutes(routes, req.url); //获取匹配到的多个路由 react-route 下的matchPath只匹配一层路由
  let promiseArrs = [];
  matchRoutersArr.forEach(function(o, i) {
    let component = o.route.component;
    if (component.loadData) {
      promiseArrs.push(component.loadData(store));
    }
    if (typeof component.styleInit === "function") {
      component.styleInit();
    }
  });

  Promise.all([...promiseArrs]).then(result => {
    doRender(req, res, context, routes, store);
  });
});

const doRender = (req, res, context, routes, store) => {
  let pourWater = store.getState();
  //调用renderRouters方法  url匹配到的那个路由 会传递一个props.route对象 做子路由可以在父路由组件里写对应实现
  console.log(content);
  const content = renderToString(
    <Provider store={store}>
      <StaticRouter location={req.url} context={context}>
        <Switch> {renderRoutes(routes)}</Switch>
      </StaticRouter>
    </Provider>
  );

  console.log("globalStyle--->", globalData.globalStyle);
  res.send(`<html>
    <head>
        <title>LoveRecycleSSR</title>
        <style>
          ${globalData.globalStyle.join("\r\n")}
        </style>
    </head>
    <body>
        <div id='root'>${content}</div><!-- 一个坑 root内不能有空格 换行 否则前端报错 -->
        <!-- 数据脱水 要把脱水代码放index.js前面 这样同构前台路由才能获得到 window.context数据 js是由上而下加载 -->
        <script>
          window.context = ${JSON.stringify(pourWater)}
        </script>
        <script src='/index.js'></script> 
      
    </body>
    </html>`);
};

//启动express服务器 开启服务器端渲染
app.listen(8080);
